package com.nf.practice.workdemo;

import lombok.Data;
import lombok.experimental.Accessors;
import org.junit.jupiter.api.Test;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

@Data
@Accessors(chain = true)
class TmWaterDetails {
    String dealDate;
    String dealTime;
    BigDecimal balance;


    public TmWaterDetails(String dealDate, BigDecimal balance) {
        this.dealDate = dealDate;
        this.balance = balance;
    }
    public TmWaterDetails(String dealDate, String dealTime, BigDecimal balance) {
        this.dealDate = dealDate;
        this.dealTime = dealTime;
        this.balance = balance;
    }
}

public class Main01 {
    @Test
    public void test01() {
        List<TmWaterDetails> tempTmWaterDetails = new ArrayList<>();
        BigDecimal averageBalance = null;
        if (!CollectionUtils.isEmpty(tempTmWaterDetails)) {
            averageBalance = tempTmWaterDetails.stream()
                    .map(TmWaterDetails::getBalance)
                    .reduce(BigDecimal.ZERO, BigDecimal::add)
                    .divide(BigDecimal.valueOf(tempTmWaterDetails.size()), 2, RoundingMode.HALF_UP);
        }
        System.out.println(null != averageBalance ? averageBalance : "空");
    }

    public static void main(String[] args) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        List<TmWaterDetails> dateBalanceInfos = Arrays.asList(
                new TmWaterDetails("2024-03-23","10:00:00", BigDecimal.valueOf(200)),
                new TmWaterDetails("2024-03-23","15:00:00", BigDecimal.valueOf(100)),
                new TmWaterDetails("2024-03-10","15:00:00", BigDecimal.valueOf(400)),
                new TmWaterDetails("2024-03-01","09:00:00", BigDecimal.valueOf(300)),
                new TmWaterDetails("2024-03-01","10:00:00", BigDecimal.valueOf(100)),
                new TmWaterDetails("2023-12-01","10:00:00", BigDecimal.valueOf(100)),
                new TmWaterDetails("2023-12-01","11:00:00", BigDecimal.valueOf(200)),
                new TmWaterDetails("2023-12-02","10:00:00", BigDecimal.valueOf(100)),
                new TmWaterDetails("2023-12-03","10:00:00", BigDecimal.valueOf(113))
        );
        // 按照 date 和 time 属性进行升序排序
        List<TmWaterDetails> sortedList = dateBalanceInfos.stream()
                .sorted(Comparator.comparing(TmWaterDetails::getDealDate)
                        .thenComparing(TmWaterDetails::getDealTime).reversed())
                .collect(Collectors.toList());

        List<TmWaterDetails> resultList = dateBalanceInfos.stream()
                .sorted(Comparator.comparing(TmWaterDetails::getDealDate)
                        .thenComparing(TmWaterDetails::getDealTime).reversed())
                .collect(Collectors.toMap(
                        TmWaterDetails::getDealDate,
                        detail -> detail,
                        (existing, replacement) -> existing,
                        LinkedHashMap::new))
                .values()
                .stream()
                .collect(Collectors.toList());

        // 按照 date 的年月进行分组
        Map<String, List<TmWaterDetails>> groupData = resultList.stream()
                .collect(Collectors.groupingBy(detail -> detail.getDealDate().substring(0, 7)));

        Map<String, List<TmWaterDetails>> newGroupData = new HashMap<>();

        Map<String, BigDecimal> result = new HashMap<>();
        groupData.forEach((k, v) -> {
            // 反转列表，使数据按日期升序排列
            Collections.reverse(v);
            // 补充中间缺失的日期对应的余额值
            fillMissingDates(v);
            newGroupData.put(k,v);

//            // 计算余额平均值并保留两位小数
//            double averageBalance = v.stream()
//                    .mapToDouble(TmWaterDetails::getBalance)
//                    .average()
//                    .orElse(0.0);
//
//            // 保留两位小数
//            averageBalance = Math.round(averageBalance * 100.0) / 100.0;

            BigDecimal averageBalance = v.stream()
                    .map(TmWaterDetails::getBalance)
                    .reduce(BigDecimal.ZERO, BigDecimal::add)
                    .divide(BigDecimal.valueOf(v.size()), 2, RoundingMode.HALF_UP);

            result.put(k, averageBalance);
        });


        System.out.println(result);

    }

    private static void fillMissingDates(List<TmWaterDetails> tmWaterDetails) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");

        List<TmWaterDetails> updatedList = new ArrayList<>();
        for (int i = 1; i < tmWaterDetails.size(); i++) {
            LocalDate prevDate = LocalDate.parse(tmWaterDetails.get(i - 1).dealDate, formatter);
            LocalDate currentDate = LocalDate.parse(tmWaterDetails.get(i).dealDate, formatter);
            updatedList.add(tmWaterDetails.get(i-1));
            // 补全日期
            while (!prevDate.plusDays(1).equals(currentDate)) {
                prevDate = prevDate.plusDays(1);
                BigDecimal prevBalance = tmWaterDetails.get(i - 1).balance;
                updatedList.add(new TmWaterDetails(prevDate.format(formatter), prevBalance));
            }

            // 如果是最后一个元素，单独处理
            if (i == tmWaterDetails.size() - 1) {
                updatedList.add(tmWaterDetails.get(i));
            }
        }
        tmWaterDetails.clear();
//        updatedList.add(tmWaterDetails.get(tmWaterDetails.size() - 1));
        tmWaterDetails.addAll(updatedList);
    }

}
